home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 4 / Atari Forever 4 / Atari Forever 4.iso / SERIE_AI / AI_017 / INTERNET.TOS / SOFTWARE / LANCESR / LANCEDRV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-17  |  11.5 KB  |  515 lines

  1. #include <stdio.h>
  2. #include <stddef.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <tos.h>
  6. #include <time.h>
  7. #include "lancemem.h"
  8. #include "lancedrv.h"
  9. #include "pktqueue.h"
  10. #include "pktdrv.h"
  11. #include "cookie.h"
  12. #include "inetcust.h"
  13.  
  14. #define noDEBUG
  15. #define noDEBUGINTR
  16. #define DEBUGPKT
  17. #define noDEBUGFREECNT
  18.  
  19.  
  20. int  retval;
  21. int     term = 0;
  22.  
  23. #define TIMEOUTCNT    10000            /* count down for lance to come up */
  24.  
  25. short new_stack[ISTACKSIZE/2];            /* interrupt stack */
  26. char *old_stack;                        /* must be immediately behind new_stack */
  27. void ( *ihandler )(void) = NULL;        /* pointer to interrupt handler */
  28. long old_pterm;
  29. long lnc_vector = LANCEIVEC * sizeof(char *);
  30.  
  31. int lnc_reset(void);                /* reset lance, init datastructures  */
  32. void lnc_intr(void);                /* interrupt handler */
  33. void memcopy(register char *,register char *,register int);    /* own memcopy routine */
  34. void (* old_berr)();                /* old bus error handler */
  35. extern void berr_catch(void);        /* bus error handler for ST/STE */
  36. extern void berr_tt_catch(void);    /* bus error handler for TT */
  37. int memok;
  38.  
  39.  
  40. volatile TMD    *tmd_sent;        /* last sent packet */
  41. PKTBUF             *pkt_ring[RECVBUFFS];    /* pointers to packets waiting for recv */
  42. int                pkt_recv;        /* index of buufer receiving next packet */
  43. PKTPOOL            *p_free;        /* queue of free packets */
  44. u_short            freecnt;        /* number of free packets */
  45. volatile int    pkt_sent = 0;    /* flag if pkt is successfully sent */
  46. HADDR    my_haddr;                /* my hardware address */
  47.  
  48. procref ext_tab[8] =                 /* subfunction table */
  49. {
  50.     net_reset,
  51.     net_open,
  52.     net_release,
  53.     net_send,
  54.     net_getadr,
  55.     net_info,
  56.     (procref)net_pktalloc,
  57.     net_pktfree
  58. };
  59.  
  60. PROTOCOL protos[MAXPROTOCOLS];        /* protocols to serve */
  61. int protocols = 0;                    /* number of active protocols */
  62.  
  63. et_stat stat;                        /* statistics block */
  64.  
  65. long net_resets(void);
  66.  
  67. int read_inf(void)
  68. {
  69. COOKIE *cookie;
  70.  
  71.     cookie = get_cookie(INETCUSTCOOKIE);
  72.     if(!cookie || !cookie->val) return(0);
  73.     memcopy(my_haddr,((INETCUST *)(cookie->val))->haddr,(int)sizeof(HADDR));
  74.     return(1);
  75. }
  76.  
  77.  
  78.  
  79.  
  80. int net_info(int len, char *buf)
  81. {
  82.     if(!buf) return(0);
  83.     if(buf == (char *)1L) 
  84.     {
  85.         lnc_reset();
  86.         return(0);
  87.     }
  88.     stat.st_free = freecnt;
  89.     memcopy(buf,(char *)&stat,(size_t)len<sizeof(stat)?len:(int)sizeof(stat));
  90.     return(len);
  91. }
  92.  
  93.  
  94. int net_open(int type, int (*handler)(int,char *))
  95. {
  96. int i,new;
  97.     
  98.     if(!handler) return(EPARAM);
  99.     if(protocols >= MAXPROTOCOLS) return(EPROTAVAIL);
  100.     new = -1;
  101. #ifdef RESET_ON_OPEN
  102.     if(!protocols)
  103.     {
  104.         net_resets();
  105.         if(ihandler == NULL) return(EINIT);
  106.     }
  107. #endif
  108.     for(i=0; i<MAXPROTOCOLS; i++)
  109.     {            /* protocol already used */
  110.         if(protos[i].type == type) return(EPROTUSED);
  111.         if(protos[i].type == ET_UNUSED &&  new<0 ) new = i; /* find first free entry */
  112.     }
  113.     if(new<0) new = protocols;
  114.     protocols++;
  115.     protos[new].handler = handler;
  116.     protos[new].recvd = 0;
  117.     protos[new].sent = 0;
  118.     protos[new].type = type;
  119.     return(new);
  120. }
  121.  
  122.  
  123. int net_release(int type)
  124. {
  125. int i;
  126.     if(!protocols) return(EPROTUSED);
  127.     if(type == ET_UNUSED) return(EPROTUSED);
  128.     for(i=0; i<MAXPROTOCOLS; i++)
  129.         if(protos[i].type == type) break;
  130.     if(i==MAXPROTOCOLS) return(EPROTUSED);
  131.     protocols--;
  132.     if(!protocols)
  133.     {
  134.         *RCP_RAP = CSR0;
  135.         *RCP_RDP = CSR0_STOP;
  136.         ihandler = NULL;
  137.     }
  138.     protos[i].type = ET_UNUSED;
  139.     protos[i].handler = NULL;
  140.     return(protocols);
  141. }
  142.  
  143.  
  144. int net_send(int len, char *buf)
  145. {
  146. register int *rdp;
  147. register TMD *tmd;
  148. register long timeout;
  149.  
  150.     if(!buf || !len || (buf < (char *)PPKT) || (buf > (char *)PPOOL)) return(EPARAM);
  151.     rdp = RCP_RDP;
  152.     pkt_sent = 0;
  153.     if(len < 60) len = 60;
  154.     if(len > (int)sizeof(PACKET)) return(EPKTLEN);
  155.     *(rdp+1) = CSR0;
  156.     if(!(*rdp & CSR0_TXON)) return(EINIT);
  157.     tmd = (TMD *)tmd_sent;
  158.     if((tmd->tmd1 & OWN) == OWN_CHIP) return(EINIT);
  159.     tmd->ladr = (u_short)(buf);                /* point to packet to send */
  160.     tmd->tmd2 = -len;
  161.     tmd->tmd3 = 0;
  162.     tmd->tmd1 = (STP | ENP | OWN_CHIP);    /* start/end of packet */
  163.     timeout = clock() + 3*TIMEOUT;
  164.     while(!pkt_sent && !tmd->tmd3 && clock() < timeout);   /* wait till packet sent */
  165.     if(clock() > timeout) return(ETIMEOUT);
  166.     if(tmd->tmd3 || pkt_sent < 0) return(ECOLLISION);
  167.     return(len);
  168. }
  169.  
  170.  
  171. int    net_getadr(int len, char *buf)
  172. {
  173. register LNCMEM *mem;
  174.  
  175.     if(len>=(int)sizeof(HADDR))
  176.     {
  177.         mem = (LNCMEM *)RCP_MEMBOT;
  178.         buf[0] = mem->init.haddr[1];
  179.         buf[1] = mem->init.haddr[0];
  180.  
  181.         buf[2] = mem->init.haddr[3];
  182.         buf[3] = mem->init.haddr[2];
  183.  
  184.         buf[4] = mem->init.haddr[5];
  185.         buf[5] = mem->init.haddr[4];
  186.         return((int)sizeof(HADDR));
  187.     }
  188.     return(0);
  189. }
  190.  
  191.  
  192. long net_resets(void)
  193. {
  194. int i;
  195.     for(i=0;i<MAXPROTOCOLS;i++)  /* init protocol table */
  196.       {
  197.            protos[i].type = ET_UNUSED;
  198.            protos[i].handler = NULL;
  199.         protos[i].recvd = 0;
  200.         protos[i].sent = 0;
  201.        }
  202.        protocols = 0;
  203.     p_free = p_init(MAXPKT,PPOOL,PPKT);        /* init free packets */
  204.     freecnt = MAXPKT;
  205.     for(i=0; i< RECVBUFFS; i++)
  206.     {
  207.         pkt_ring[i] = ap_getpkt(ET_FREE,p_free);    /* retrieve packet for receive */
  208.         if(!pkt_ring[i]) return(EINIT);
  209.         freecnt--;
  210.     }
  211.     return(lnc_reset());
  212. }
  213.  
  214. int net_reset(void)
  215. {
  216.     Supexec(net_resets);
  217.     if( !ihandler) 
  218.         return(EINIT);
  219.     else
  220.         return(0);
  221. }
  222.  
  223.  
  224. PKTBUF *net_pktalloc(protocol)
  225. u_short protocol;
  226. {
  227. register PKTBUF *pkt;
  228.     if(!p_free) net_reset();
  229.     if(freecnt <= 1) return(NULL);
  230.     pkt = ap_getpkt(protocol,p_free);
  231.     if(pkt)
  232.         freecnt--;
  233.     return(pkt);
  234. }
  235.  
  236.  
  237. int net_pktfree(p_pkt)
  238. PKTBUF *p_pkt;
  239. {
  240.     if(!p_free || !p_pkt || (p_pkt < PPKT) || (p_pkt > (PKTBUF *)PPOOL))
  241.     {
  242. #ifdef DEBUGPKT
  243.         Cconws("Packet out of band\r\n");
  244. #endif
  245.         return(FALSE);
  246.     }
  247.     if(((long)p_pkt - (long)PPKT) % sizeof(PKTBUF))
  248.     {
  249. #ifdef DEBUGPKT
  250.         Cconws("Packet misaligned\r\n");
  251. #endif
  252.         return(FALSE);
  253.     }
  254.     if(ap_putpkt(p_free,p_pkt))
  255.     {
  256.         freecnt++;
  257.         return(TRUE);
  258.     }
  259.     return(FALSE);
  260. }
  261.  
  262. /*******************************************************************/
  263. /*******************************************************************/
  264.  
  265. #ifdef DEBUG
  266. char str[40];
  267. #endif
  268.  
  269.  
  270. void lnc_intr(void)
  271. {
  272. register int         csr0;
  273. register int        type;
  274. register int        i;
  275.  
  276. register int         *rdp;
  277. register et_stat    *et_stat;
  278. register TMD        *md;
  279. register PKTBUF        *pkt;
  280.     
  281.     rdp = RCP_RDP;        /* register data port */
  282.     *(rdp+1) = CSR0;
  283.     csr0 = *rdp;
  284.     if(!(csr0 & CSR0_INTR)) return;
  285.     et_stat = &stat;
  286. #ifdef DEBUGINTR
  287.     if(protocols>0)
  288.     {
  289.         strcpy(str,"pkt intr: ");
  290.         itoa(csr0,str+strlen(str),16);
  291.         strcat(str,"\r\n");
  292.         Cconws(str);
  293.     }
  294. #endif
  295.     
  296.     et_stat->st_err = csr0;
  297.     et_stat->st_intr++;
  298.     if(csr0 & CSR0_IDON)
  299.         *(rdp) = CSR0_IDON;
  300.     else if(csr0 & CSR0_RINT)
  301.     {
  302.       do
  303.       {
  304.         (RMD *)md  = &PRMD[pkt_recv];
  305.         *rdp = CSR0_RINT;
  306.         if(!(((RMD *)md)->rmd1 & ERR))    /* packet ok */
  307.         {
  308. /*            pkt = pkt_ring[pkt_recv]; */
  309.             pkt = (PKTBUF *)((long)RCP_MEMBOT+(((RMD *)md)->ladr));
  310.             type = pkt->et_type;
  311.             et_stat->st_received++;
  312.             if(protocols > 0)
  313.             {
  314. #ifdef DEBUG
  315.                 itoa(type,str,16);
  316.                 Cconws(str);
  317.                 Cconws(" from ");
  318.                 ltoa((long)pkt,str,16);
  319.                 Cconws(str);
  320.                 Cconws("\r\n");
  321. #endif
  322.                 for(i=0;i<MAXPROTOCOLS; i++)
  323.                 {
  324.                     if(protos[i].type == type && freecnt > 0)
  325.                     {                    /* must have one packet free */
  326.                         if(protos[i].handler && 
  327.                            protos[i].handler(((RMD *)md)->mcnt,(char *)pkt))
  328.                         {    
  329.                                     /* retrieve one packet for receive */
  330.                             pkt_ring[pkt_recv] = ap_getpkt(ET_FREE,p_free);
  331.                             freecnt--;
  332.                                             /* set new receive packet */
  333.                             ((RMD *)md)->ladr = (u_short)(pkt_ring[pkt_recv]);
  334.                             et_stat->st_got++;
  335.                             protos[i].recvd++;
  336.                         }
  337.                         break;
  338.                     }
  339.                 }
  340.             }
  341.         }
  342.         else
  343.         {
  344.               if(((RMD *)md)->rmd1 & CRC)
  345.                 et_stat->st_crc++;
  346.             lnc_reset();
  347.             return;
  348.         }
  349.         ((RMD *)md)->mcnt = 0;            /* free packet */
  350.         ((RMD *)md)->rmd1 = OWN_CHIP;    /* give packet back to lance */
  351.         pkt_recv++;
  352.         if(pkt_recv >= RECVBUFFS) pkt_recv = 0;
  353.       } while((PRMD[pkt_recv].rmd1 & OWN) == OWN_HOST);
  354.     }
  355.     else if(csr0 & CSR0_TINT)
  356.     {
  357.         md = (TMD *)tmd_sent;
  358.         if((md->tmd1 & OWN) == OWN_HOST)  /* packet given back to host */
  359.         {
  360.             if((md->tmd1) & ERR)
  361.             {
  362.                 pkt_sent = -1;
  363.                 et_stat->st_xmiterr++;
  364.             }
  365.             else
  366.             {
  367.                 pkt_sent = 1;
  368.                 et_stat->st_sent++;
  369.                 if(md->tmd1 & (MORE | ONE | DEF))
  370.                     et_stat->st_collision++;
  371.             }
  372.         }
  373.         else
  374.             et_stat->st_xmiterr++;
  375.         *rdp = CSR0_TINT;    /* clear interrupt bit */
  376.     }
  377.     else if(csr0 & CSR0_ERR)
  378.     {
  379.         et_stat->st_missed++;
  380.         *(rdp+1) = 0;
  381.         *rdp = CSR0_CERR | CSR0_MERR | CSR0_BABL | CSR0_MISS;
  382.     }
  383.     *(rdp+1) = CSR0;
  384.     *rdp = CSR0_INEA;
  385. }
  386.  
  387.  
  388. int lnc_reset(void)
  389. {
  390. register LNCMEM *mem;
  391. register TMD    *md;
  392. register u_long i;
  393. register int *rdp;
  394.  
  395.     rdp = RCP_RDP;
  396.     *(rdp+1) = CSR0;
  397.     *rdp = CSR0_STOP;
  398.         /* init data structures */
  399.         
  400.     mem = (LNCMEM *)RCP_MEMBOT;
  401.     mem->init.mode = 0;        /* mode word */
  402.     
  403.     mem->init.haddr[5] = my_haddr[4];
  404.     mem->init.haddr[4] = my_haddr[5];
  405.     mem->init.haddr[3] = my_haddr[2];
  406.     mem->init.haddr[2] = my_haddr[3];
  407.     mem->init.haddr[1] = my_haddr[0];
  408.     mem->init.haddr[0] = my_haddr[1];
  409.     
  410.     mem->init.laf[0] = 0;    /* logical adress filter */
  411.     mem->init.laf[1] = 0;    /* logical adress filter */
  412.  
  413.     mem->init.rdrp.drp_lo = (u_short)offsetof(LNCMEM,rmd[0]);
  414. /*    ((u_long)&(PRMD[0]));    */ /* receive ring descr. pointer */
  415.     mem->init.rdrp.drp_hi = 0;
  416.     mem->init.rdrp.len = RECVRLEN;
  417.     
  418.     mem->init.tdrp.drp_lo = (u_short)offsetof(LNCMEM,tmd);
  419. /*    ((u_long)&PTMD);    */    /* transmit ring descr. pointer */
  420.     mem->init.tdrp.drp_hi = 0;
  421.     mem->init.tdrp.len = XMITRLEN;
  422.  
  423.     md = &mem->tmd;
  424.     md->ladr = 0;                            /* dont know adress of packet to send */
  425.     md->tmd1 = OWN_HOST;
  426.     md->tmd2 = 0;                            /* zero pkt size */
  427.     md->tmd3 = 0;
  428.     for(i=0; i< RECVBUFFS; i++)
  429.     {
  430.         (RMD *)md = mem->rmd+i;
  431.         ((RMD *)md)->ladr = (u_short)((char *)pkt_ring[i]);
  432.         ((RMD *)md)->rmd1 = OWN_CHIP;
  433.         ((RMD *)md)->rmd2 = -MAXPKTLEN;            /* 2's complement (maximum size) */
  434.         ((RMD *)md)->mcnt = 0;
  435.     }
  436.     tmd_sent = &mem->tmd;
  437.     pkt_recv = 0;
  438.     *(rdp+1) = CSR3;
  439.     *rdp = CSR3_BSWP;
  440.     *(rdp+1) = CSR2;
  441.     *rdp = 0;
  442.     *(rdp+1) = CSR1;
  443.     *rdp = 0;
  444.     *(rdp+1) = CSR0;
  445.     *rdp = CSR0_STRT | CSR0_INIT;
  446.     i = TIMEOUTCNT * 100;
  447.     do
  448.     {
  449.         if(*rdp & CSR0_IDON) break;
  450.     }while(--i > 0);
  451.     if(i<=0 || (*rdp & CSR0_ERR))
  452.     {
  453.         *rdp = CSR0_STOP;
  454.         ihandler = NULL;
  455.         return(EINIT);
  456.     }
  457.     ihandler = lnc_intr;
  458.     *rdp = CSR0_IDON;        /* clear idon-bit */
  459.     *rdp = CSR0_INEA;        /* enable interrupts */
  460.     return(0);
  461. }
  462.  
  463. main()
  464. {
  465. COOKIE *cookie;
  466. void (*call)(void);
  467.  
  468.     Cconws("\r\nPacket driver V1.1 for RieblCard Plus ");
  469.        cookie = get_cookie(PKTCOOKIE);
  470.     if(cookie)
  471.     {
  472.         (long)call = ((long *)cookie->val)[NETRESET];
  473.         call();        /* reset network */
  474.         Cconws("\r\nexisting driver reset\r\n");
  475.         return(0);
  476.     }
  477.     memok = 0;
  478.     old_berr = Setexc(2,(void (*)())(-1));
  479.     cookie = get_cookie(MACHINECOOKIE);
  480.     if(!cookie || ((cookie->val >> 16) != 2))
  481.         Setexc(2,berr_catch);
  482.     else
  483.         Setexc(2,berr_tt_catch);
  484.     *RCP_MEMBOT=0xaa;
  485.     Setexc(2,old_berr);
  486.     if(memok)
  487.     {
  488.         Cconws("\r\nEthernet Card NOT found\r\n\a");
  489.         return(0);
  490.     }
  491.        if(!read_inf())
  492.        {
  493.            Cconws("INETCUST not installed !!\r\n");
  494.        }
  495.        else
  496.        {
  497. #ifdef DEBUGFREECNT
  498.            Cconws("freecnt at 0x");
  499.            Cconws(ltoa((long)&freecnt,(char *)new_stack,16));
  500.            Cconws("\r\n\a\a");
  501. #endif
  502.         ihandler = NULL;
  503.         Supexec(lnc_install);
  504.         if(net_reset() < 0)
  505.            {
  506.                Setexc(LANCEIVEC, (void (*)())old_intr);
  507.                Cconws("Cannot init Ethernet Card\r\n\a");
  508.                return(0);
  509.            }
  510.         add_cookie(PKTCOOKIE,(long)ext_tab);
  511.         Cconws("installed\r\n(c) hw,pm fortec 1991,1992\r\n");
  512.         Ptermres(_PgmSize,0);
  513.     }
  514.     return(0);
  515. }